package web.service.rest;

import cn.edu.hit.mongodb.Utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.MongoClient;
import com.mongodb.client.model.Filters;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.apache.commons.lang3.StringUtils;
import cn.edu.hit.core.Document;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static web.service.rest.MqConfigure.*;

/**
 * Created by Wang on 2018/5/28.
 */

@Path("/fft")
public class FFTService {


    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Map test() {
        return Collections.singletonMap("state", true);
    }

    /**
     * 用于信号展示
     */
    private static Timer portTimer = new Timer();
    private static String portId = null;
    private static long offsetMs = 0;

    private static TimerTask portTask = new TimerTask() {
        private static final String EXCHANGE_NAME = "TMM_AD_MessagingExchanger";
        ConnectionFactory factory = null;
        Connection connection = null;
        Channel channel = null;
        ObjectMapper mapper = new ObjectMapper();

        {
            factory = new ConnectionFactory();
            factory.setHost(mqHost);
            factory.setPort(mqPort);
            factory.setUsername(mqUser);
            factory.setPassword(mqPassword);

            try {
                connection = factory.newConnection();
                channel = connection.createChannel();
                channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            long timestamp = new Date().getTime() - offsetMs;
            System.out.println(timestamp + portId);
            if (StringUtils.isNotBlank(portId)) {
                List<Document> signals = Utils.getLastRecords("features",
                        Filters.and(
                                Filters.exists("signalType", true),
                                Filters.eq("portId", portId)
                        ).toBsonDocument(null, MongoClient.getDefaultCodecRegistry()), timestamp);
                if (signals != null && signals.size() > 0) {
                    String message = null;
                    Document document = signals.get(0);
                    List<Double> values = (List<Double>) document.get("value", new ArrayList<>());
                    if (values != null && values.size() > 0)
                        try {
                            Map dataMap = new HashMap();
                            dataMap.put("time", timestamp);
                            dataMap.put("device", "fft-data");
                            dataMap.put("range", new int[]{0, 0});
                            dataMap.put("value", new int[]{0});
                            Map data = new HashMap();
                            data.put("frequencies", IntStream.range(0, 512).boxed().collect(Collectors.toList()));
                            data.put("values", values);
                            dataMap.put("data", data);
                            message = mapper.writeValueAsString(dataMap);
//                            System.out.println(message);
                            channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                            this.cancel();
                        } catch (IOException e) {
                            e.printStackTrace();
                            this.cancel();
                        }
                }
            }
        }
    };

    static {
        portTimer.scheduleAtFixedRate(portTask, 0, 500);
    }

    @GET
    @Path("/changePort/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Map changePort(@PathParam("id") String signalId,
                          @QueryParam("offset") @DefaultValue("0") long offset/*时间偏移 单位ms*/) {
//        portTimer.cancel();
        portId = signalId;
        offsetMs = offset;
        return Collections.singletonMap("_id", signalId);
    }

    public static void main(String[] args) throws IOException {
        portId = "5b44958cddcb1f333cbebcab";
        Date date = new Date();
        date.setHours(17);
        date.setMinutes(03);
        offsetMs = new Date().getTime() - date.getTime();
        System.in.read();
    }
}
